global with sharing class SetApprovers
{
    Webservice static List<User> getUsers()
    {
        List<User> dataSourceList = new List<User>();
        return dataSourceList;
    }

    Webservice static List<CallidusDataSource__c> getDataSourceUsers()
    {
        List<CallidusDataSource__c> dataSourceList = new List<CallidusDataSource__c>();
        
        DataAccessControlUtil dacu = new DataAccessControlUtil();
        SObject cdsObj = new CallidusDataSource__c();
        Map<String, Schema.SObjectField> cdsFieldMap = dacu.getFieldMap(cdsObj);
        
        String[] cdsExpectedFields = new String[]{'Id', 'Name', 'UserID__c'}; 
        Set<String> allowedROFields = dacu.getAccessibleFields(cdsObj, cdsFieldMap, cdsExpectedFields);
        String formSoql = '';
        if(!allowedROFields.isEmpty())
        {
            formSoql = 'Select ';
            for(String roField: allowedROFields)
            {
                formSoql += roField+', ';
            }
            formSoql = formSoql.substring(0, formSoql.length() - 2);
            
            //Not filtering using the ownerId as the records are used by all Admins for Plan Generation. 
            formSoql += ' from CallidusDataSource__c where IsActive__c = true limit 1000 ';

            dataSourceList = Database.query(formSoql);//[select Id, UserID__c from CallidusDataSource__c]) 
        }
        return dataSourceList;
    }


    Webservice static String saveApprovers(Approvers__c app)
    {
        SObject appObj = new Approvers__c();
        DataAccessControlUtil dacu = new DataAccessControlUtil();
        //Enters only if the USer has permission to create create and delete the object
        if(dacu.isCreateableObjectByUser(appObj) == 'success' && dacu.isDeleteableObjectByUser(appObj) == 'success')
        {       
            String[] approverExpectedFields = new String[]{'Id','Template__c'};
            Map<String, Schema.SObjectField> approverFieldMap = dacu.getFieldMap(appObj);
            Set<String> allowedROFields = dacu.getAccessibleFields(appObj, approverFieldMap, approverExpectedFields);
            String formSoql = '';
            if(!allowedROFields.isEmpty())
            {
                formSoql = 'Select ';
                for(String roField: allowedROFields)
                {
                    formSoql += roField+', ';
                }
                formSoql = formSoql.substring(0, formSoql.length() - 2);
                
                String templateVal = app.Template__c;
                //Not filtering using the ownerId as the records are used by all Admins.
                if(templateVal != null) 
                	formSoql += ' from Approvers__c where template__c = :templateVal';
                else
            		formSoql += ' from Approvers__c where template__c = null '; 
            		
                Approvers__c[] approver = Database.query(formSoql);//[select Id from Approvers__c  where Template__c = :app.Template__c];
                if(approver.size() > 0)
                {
                    delete approver;
                }
                if(app.Level1__c != null)
                    insert app;
            }
        } 
        return 'success';
    }
    
    WebService static Approvers__c getApproverRecord(String templateId)
    {
        String[] approverExpectedFields = new String[]{'Admin__c','Template__c','Final_Approver__c','Final_Approver_Date__c','Level1__c','Level2__c','Level3__c','Level4__c','Level5__c','Level6__c','Level7__c','Level8__c','Level9__c','Level10__c','Level11__c','Level12__c','Level13__c','Level14__c','Level15__c','Level1_Due_Date__c','Level2_Due_Date__c','Level3_Due_Date__c','Level4_Due_Date__c','Level5_Due_Date__c','Level6_Due_Date__c','Level7_Due_Date__c','Level8_Due_Date__c','Level9_Due_Date__c','Level10_Due_Date__c','Level11_Due_Date__c','Level12_Due_Date__c','Level13_Due_Date__c','Level14_Due_Date__c','Level15_Due_Date__c'};
        SObject appObj = new Approvers__c();
        DataAccessControlUtil dacu = new DataAccessControlUtil();
        Map<String, Schema.SObjectField> approverFieldMap = dacu.getFieldMap(appObj);
        Set<String> allowedROFields = dacu.getAccessibleFields(appObj, approverFieldMap, approverExpectedFields);
        String formSoql = '';
        if(!allowedROFields.isEmpty())
        {
            formSoql = 'Select ';
            for(String roField: allowedROFields)
            {
                formSoql += roField+', ';
            }
            formSoql = formSoql.substring(0, formSoql.length() - 2);
            
            //Not filtering using the ownerId as the records are used by all Admins. 
            formSoql += ' from Approvers__c ';
            
            //get Accessible fields for the Where clause filter
            approverExpectedFields = new String[]{'Template__c'};
            allowedROFields = dacu.getAccessibleFields(appObj, approverFieldMap, approverExpectedFields);
            if(!allowedROFields.isEmpty())
            {
                formSoql += ' where ';
                for(String roField: allowedROFields)
                {
                    formSoql += roField+' = :templateId  order by CreatedDate desc limit 1 ';
                }
                if(formSoql.contains(','))
                {
                    Approvers__c[] app = Database.query(formSoql);//[select Admin__c, Template__c, Final_Approver__c, Final_Approver_Date__c, Level1__c, Level2__c, Level3__c, Level4__c, Level5__c, Level6__c, Level7__c, Level8__c, Level9__c, Level10__c, Level11__c, Level12__c, Level13__c, Level14__c, Level15__c, Level1_Due_Date__c, Level2_Due_Date__c, Level3_Due_Date__c, Level4_Due_Date__c, Level5_Due_Date__c, Level6_Due_Date__c, Level7_Due_Date__c, Level8_Due_Date__c, Level9_Due_Date__c, Level10_Due_Date__c, Level11_Due_Date__c, Level12_Due_Date__c, Level13_Due_Date__c, Level14_Due_Date__c, Level15_Due_Date__c from Approvers__c  where Template__c = :templateId order by CreatedDate desc limit 1]
                    if(app.size() > 0)
                        return app[0];
                }
            }
        }        
        return null;
    }

	WebService static BatchDetail__c[] getAdditionUserDetails()
	{
		BatchDetail__c[] batchDetailList;
		
        DataAccessControlUtil dacu = new DataAccessControlUtil();
        SObject bdObj = new BatchDetail__c();
        Map<String, Schema.SObjectField> bdFieldMap = dacu.getFieldMap(bdObj);
        
        String[] bdExpectedFields = new String[]{'Id', 'Field_Name__c'}; 
        Set<String> allowedROFields = dacu.getAccessibleFields(bdObj, bdFieldMap, bdExpectedFields);
        String formSoql = '';
        if(!allowedROFields.isEmpty())
        {
            formSoql = 'Select ';
            for(String roField: allowedROFields)
            {
                formSoql += roField+', ';
            }
            formSoql = formSoql.substring(0, formSoql.length() - 2);
            
            formSoql += ' from BatchDetail__c limit 1000';
            batchDetailList = Database.query(formSoql); 
        }
		
		return batchDetailList;
	}
	
    Webservice static String saveAdditionalUserDetails(BatchDetail__c[] bdList)
    {
    	
        SObject bdObj = new BatchDetail__c();
        DataAccessControlUtil dacu = new DataAccessControlUtil();
        //Enters only if the USer has permission to create create and delete the object
        if(dacu.isCreateableObjectByUser(bdObj) == 'success' && dacu.isDeleteableObjectByUser(bdObj) == 'success')
        {
            String[] bdExpectedFields = new String[]{'Id'};
            Map<String, Schema.SObjectField> bdFieldMap = dacu.getFieldMap(bdObj);
            Set<String> allowedROFields = dacu.getAccessibleFields(bdObj, bdFieldMap, bdExpectedFields);
            String formSoql = '';
            if(!allowedROFields.isEmpty())
            {
                formSoql = 'Select ';
                for(String roField: allowedROFields)
                {
                    formSoql += roField+', ';
                }
                formSoql = formSoql.substring(0, formSoql.length() - 2);
                
                formSoql += ' from BatchDetail__c ';
            
                BatchDetail__c[] batchDetails = Database.query(formSoql);
	        	if(bdList == null)
	        	{
                    delete batchDetails;
	        	}       
                if(batchDetails.size() > 0)
                {
                    delete batchDetails;
                }
                if(bdList.size() > 0)
                    insert bdList;
            }
        } 
        return 'success';
    }
    
	

    static testMethod void testCase() 
    {
        Template__c t = new Template__c(name = 'Set Approvers');
        CallidusDataSource__c cds = new CallidusDataSource__c(UserID__c = UserInfo.getUserId());
        Test.startTest();
        insert t;
        Template__c[] testT = [select name from Template__c where id = :t.id];
        system.assertEquals(t.name, testT[0].name);
        
        insert cds;
        CallidusDataSource__c[] cdsT = [select UserID__c from CallidusDataSource__c where id = :cds.id];
        system.assertEquals(UserInfo.getUserId(), cdsT[0].UserID__c);
                
        String templateId = t.id;
        System.assertEquals(getApproverRecord(templateId), null);

        Approvers__c app = new Approvers__c(Admin__c = UserInfo.getUserId(), Template__c = t.Id);
        insert app;
        Approvers__c[] appT = [select Admin__c, Template__c from Approvers__c where id = :app.id];
        system.assertEquals(UserInfo.getUserId(), appT[0].Admin__c);
        system.assertEquals(t.id, appT[0].Template__c);
        
        System.assertEquals(getApproverRecord(templateId), app);
        
        getUsers();
        getDataSourceUsers();
        
        Approvers__c app1 = new Approvers__c(Template__c = t.Id, Admin__c = UserInfo.getUserId());
        
        saveApprovers(app1);
		
		getAdditionUserDetails();
		BatchDetail__c[] bdList = new BatchDetail__c[]{};
		BatchDetail__c bd = new BatchDetail__c(Field_name__c = 'BatchDetail Test');
		bdList.add(bd);
		saveAdditionalUserDetails(bdList);
		BatchDetail__c[] bdList2 = [select Field_Name__c from BatchDetail__c];
		system.assertEquals(bdList2[0].Field_Name__c, 'BatchDetail Test');         
        Test.stopTest();
    }
    
    static testMethod void dacuTestCase() 
    {
        
        DataAccessControlUtil dacu = new DataAccessControlUtil();
        SObject sObj = new CallidusDataSOurce__c();
        Map<String, Schema.Sobjectfield> fieldsMap = dacu.getFieldMap(sObj);
        String[] expectedFieldMap = new String[]{'Id','Name'};
        Set<String> allowedFields = dacu.getAccessibleFields(sObj, fieldsMap, expectedFieldMap);
        Set<String> filteredList = dacu.getFilteredCreateableFields(fieldsMap, allowedFields);
        filteredList = dacu.getFilteredUpdateableFields(fieldsMap, allowedFields);
        system.assertEquals('success', dacu.isCreateableObjectByUser(sObj));
        system.assertEquals('success', dacu.isUpdateableObjectByUser(sObj));
        system.assertEquals('success', dacu.isDeleteableObjectByUser(sObj));
        dacu.pageMessage(sobj, 'create');
    }    

}